package com.flyqiu.flow.core.fliter;

import com.flyqiu.flow.api.context.FlyQiuFlowGlobalContext;
import com.flyqiu.flow.api.script.FlyQiuFlowScriptActuatorManage;
import com.flyqiu.flow.api.script.IVariableScope;
import com.flyqiu.common.tools.StringTools;
import com.flyqiu.flow.bpmn.base.ScriptModel;
import com.flyqiu.flow.bpmn.element.BaseProcElement;
import com.flyqiu.flow.bpmn.element.SequenceFlow;


import java.util.HashSet;
import java.util.List;
import java.util.Set;

public class NextElementQuery implements BpmnElementFilter {
    private final FlyQiuFlowScriptActuatorManage scriptManage;
    private final IVariableScope variableScope;
    private final Set<String> elementTypes = new HashSet<>();


    public void addFilterType(String elementType) {
        if (StringTools.isAllBlank(elementType)) {
            return;
        }
        elementTypes.add(elementType);
    }


    public void clearFilterType() {
        elementTypes.clear();
    }

    public NextElementQuery() {
        scriptManage = null;
        variableScope = null;
    }

    public NextElementQuery(FlyQiuFlowGlobalContext globalContext, IVariableScope variableScope) {
        this(globalContext.getFlowScriptManage(), variableScope);
    }


    public NextElementQuery(FlyQiuFlowScriptActuatorManage scriptManage, IVariableScope variableScope) {
        this.variableScope = variableScope;
        this.scriptManage = scriptManage;
    }


    @Override
    public boolean filter(int level, BaseProcElement flowElement) {
        return true;
    }

    @Override
    public boolean handlerSequenceFlow(SequenceFlow sequenceFlow) {
        if (null == scriptManage || null == variableScope) {
            return true;
        }
        List<ScriptModel> conditionalExpression = sequenceFlow.getConditionalExpression();
        if (conditionalExpression == null || conditionalExpression.isEmpty()) return true;
        return scriptManage.executeBooleanHasTrue(conditionalExpression, variableScope);
    }

    @Override
    public boolean selectedElementType(String elementType) {
        return elementTypes.contains(elementType);
    }

    @Override
    public boolean continueNextLevel(int currentLevel, int nextLevel) {
        return nextLevel < 1;
    }
}
